﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;
using Djs.Tools.Tresor.Properties;

namespace Djs.Tools.Tresor.Gui
{
    #region TitlePanel
    public class TitlePanel : StdPanel
    {
        public TitlePanel()
        {
            this.Init();
        }
        private void Init()
        {
            this._CloseBtn = new FlatActiveButton();
            this.SuspendLayout();
            this.Controls.Add(this._CloseBtn);

            this._CloseBtn.Anchor = AnchorStyles.Top | AnchorStyles.Left;
            this._CloseBtn.Image = Resources.dialog_cancel_3_22;
            this._CloseBtn.ImageStd = Resources.dialog_cancel_3_22;
            this._CloseBtn.ImageHot = Resources.dialog_cancel_4_22;
            this._CloseBtn.ImageDown = Resources.dialog_cancel_2_22;
            this._CloseBtn.Location = new System.Drawing.Point(908, 1);
            this._CloseBtn.Size = new System.Drawing.Size(26, 26);
            this._CloseBtn.Click += this._CloseBtn_Click;

            this.Size = new System.Drawing.Size(940, 28);
            this.Font = Form.DefaultFont.CreateSimilar(1.15f, true, null, null);
            this.FromBackColor = SystemColors.GradientActiveCaption;
            this.SizeChanged += new EventHandler(TitlePanel_SizeChanged);
            this._TitleIcon = Resources.view_grid_22;
            this._CloseAction = TitlePanelCloseAction.Close;

            this.ResumeLayout(false);
            this.PerformLayout();
        }
        private void TitlePanel_SizeChanged(object sender, EventArgs e)
        {
            this._CloseBtn.Location = new Point(this.Width - this._CloseBtn.Width - 8, 1);
        }
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [Browsable(false)]
        private FlatActiveButton _CloseBtn;
        private void _CloseBtn_Click(object sender, EventArgs e)
        {
            Form form = this.FindForm();
            if (form == null) return;
            switch (this._CloseAction)
            {
                case TitlePanelCloseAction.Close:
                    form.Close();
                    break;
                case TitlePanelCloseAction.Hide:
                    form.Hide();
                    break;
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            float x = 6f;

            Image icon = this.TitleIcon;
            if (icon != null)
            {
                Rectangle area = new Rectangle(2, 2, 24, 24);
                e.Graphics.DrawImage(icon, area);
                x = area.Right + 3;
            }

            string text = this.Title;
            if (!String.IsNullOrEmpty(text))
            {
                using (Brush b = new SolidBrush(this.ForeColor))
                {
                    e.Graphics.DrawString(text, this.Font, b, new PointF(x, 7f));
                }
            }
        }

        [RefreshProperties(RefreshProperties.All)]
        [NotifyParentProperty(true)]
        [DefaultValue("")]
        [Description("Titulkový text")]
        [Category(GuiConst.CATEGORY)]
        public string Title { get { return this._Title; } set { this._Title = value; this.RePaint(); } } private string _Title;

        [RefreshProperties(RefreshProperties.All)]
        [NotifyParentProperty(true)]
        [DefaultValue("")]
        [Description("Ikona před titulkem")]
        [Category(GuiConst.CATEGORY)]
        public Image TitleIcon { get { return this._TitleIcon; } set { this._TitleIcon = value; this.RePaint(); } } private Image _TitleIcon;

        [Description("Akce po stisknutí tlačítka Close")]
        [Category(GuiConst.CATEGORY)]
        public TitlePanelCloseAction CloseAction { get { return this._CloseAction; } set { this._CloseAction = value; } } private TitlePanelCloseAction _CloseAction;
    }
    public enum TitlePanelCloseAction
    {
        None,
        Close,
        Hide
    }
    #endregion
    #region SavePanel
    public class SavePanel : StdPanel
    {
        public SavePanel()
        {
            this.Init();
        }
        private void Init()
        {
            this._SaveBtn = new FlatActiveButton();
            this.SuspendLayout();
            this.Controls.Add(this._SaveBtn);

            this._SaveBtn.Anchor = AnchorStyles.Top | AnchorStyles.Left;
            this._SaveBtn.Image = Resources.media_floppy_3_5_s;
            this._SaveBtn.ImageHot = Resources.media_floppy_3_5_a;
            this._SaveBtn.ImageStd = Resources.media_floppy_3_5_s;
            this._SaveBtn.Location = new System.Drawing.Point(836, 1);
            this._SaveBtn.Size = new System.Drawing.Size(99, 32);
            this._SaveBtn.Text = "Save";
            this._SaveBtn.ImageAlign = System.Drawing.ContentAlignment.MiddleRight;
            this._SaveBtn.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
            this._SaveBtn.Click += this._SaveBtn_Click;

            this.Size = new System.Drawing.Size(940, 36);
            this.ToBackColor = SystemColors.GradientActiveCaption;
            this.GradientOrientation = Orientation.Vertical;
            this.SizeChanged += new EventHandler(SavePanel_SizeChanged);
            this.ResumeLayout(false);
            this.PerformLayout();
        }

        void SavePanel_SizeChanged(object sender, EventArgs e)
        {
            this._SaveBtn.Location = new Point(this.Width - this._SaveBtn.Width - 5, 1);
        }
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [Browsable(false)]
        public bool ContainsChange
        {
            get { return this._ContainsChange; }
            set
            {
                if (this._ContainsChange != value)
                {
                    this._ContainsChange = value;
                    this.OnContainsChangeChanged();
                    this._ShowButtons();
                }
            }
        }
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [Browsable(false)]
        private FlatActiveButton _SaveBtn;
        private bool _ContainsChange;
        private void _ShowButtons()
        {

        }
        private void _SaveBtn_Click(object sender, EventArgs e)
        {
            this.OnSaveButtonClick();
        }

        protected virtual void OnContainsChangeChanged()
        {
            if (this.ContainsChangeChanged != null)
                this.ContainsChangeChanged(this, EventArgs.Empty);
        }
        protected virtual void OnSaveButtonClick()
        {
            if (this.SaveButtonClick != null)
                this.SaveButtonClick(this, EventArgs.Empty);
        }
        [Description("Událost po změně hodnoty \"ContainsChange\", formulář může reagovat změnou ve status baru.")]
        [Category(GuiConst.CATEGORY)]
        public event EventHandler ContainsChangeChanged;
        [Description("Událost po kliknutí na button \"Uložit\", formulář by měl událost ošetřit.")]
        [Category(GuiConst.CATEGORY)]
        public event EventHandler SaveButtonClick;

        [Description("Po uložení tlačítkem \"Uložit\" se formulář zavře. Formulář bude mít hodnotu OK.")]
        [Category(GuiConst.CATEGORY)]
        public bool CloseFormAfterSave { get; set; }

        [Description("Text tlačítka \"Uložit\".")]
        [Category(GuiConst.CATEGORY)]
        public string SaveButtonText { get { return this._SaveBtn.Text; } set { this._SaveBtn.Text = value; } }
        [Description("Obrázek tlačítka \"Uložit\".")]
        [Category(GuiConst.CATEGORY)]
        public Image SaveButtonImage { get { return this._SaveBtn.Image; } set { this._SaveBtn.Image = value; } }
    }
    #endregion
    #region StdPanel
    public class StdPanel : Panel
    {
        public StdPanel()
        {
            this.Init();
        }
        private void Init()
        {
            this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor | ControlStyles.OptimizedDoubleBuffer, true);
            this.FromBackColor = SystemColors.Control;
            this.ToBackColor = SystemColors.Control;
            this.GradientOrientation = Orientation.Horizontal;
            this.ResizeRedraw = true;
        }
        protected void RePaint()
        {
            this.Invalidate();
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            // neprovedeme: base.OnPaint(e);

            float angle = (this.GradientOrientation == Orientation.Horizontal ? 0f : 90f);
            Rectangle area = new Rectangle(0, 0, this.Width, this.Height);
            using (LinearGradientBrush lgb = new LinearGradientBrush(area, this.FromBackColor, this.ToBackColor, angle))
            {
                e.Graphics.FillRectangle(lgb, area);
            }
        }

        [RefreshProperties(RefreshProperties.All)]
        [NotifyParentProperty(true)]
        [DefaultValue(typeof(Color), "255, 0, 0")]
        [Description("Barva vlevo")]
        [Category(GuiConst.CATEGORY)]
        public Color FromBackColor { get { return this._FromBackColor; } set { this._FromBackColor = value; this.RePaint(); } } private Color _FromBackColor;

        [RefreshProperties(RefreshProperties.All)]
        [NotifyParentProperty(true)]
        [DefaultValue(typeof(Color), "192, 192, 216")]
        [Description("Barva vlevo")]
        [Category(GuiConst.CATEGORY)]
        public Color ToBackColor { get { return this._ToBackColor; } set { this._ToBackColor = value; this.RePaint(); } } private Color _ToBackColor;

        [RefreshProperties(RefreshProperties.All)]
        [NotifyParentProperty(true)]
        [DefaultValue(typeof(Orientation), "Horizontal")]
        [Description("Orientace barevného přechodu")]
        [Category(GuiConst.CATEGORY)]
        public Orientation GradientOrientation { get { return this._GradientOrientation; } set { this._GradientOrientation = value; this.RePaint(); } } private Orientation _GradientOrientation;

    }
    #endregion
    #region LinePanel
    public class LinePanel : Panel
    {
        public LinePanel()
        {
            this.Init();
        }
        private void Init()
        {
            this.Font = Form.DefaultFont.CreateSimilar(1.10f, true, null, null);
            this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor | ControlStyles.OptimizedDoubleBuffer, true);
            this.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right;
            this.Height = 4;
            this._LineColorTop = SystemColors.GradientActiveCaption;
            this._LineColorBottom = Color.DarkGray;
            this.BorderStyle = System.Windows.Forms.BorderStyle.None;
            this.ResizeRedraw = true;
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            int y = 1;

            string text = this._Title;
            if (!String.IsNullOrEmpty(text))
            {
                SizeF size = e.Graphics.MeasureString(text, this.Font);
                using (SolidBrush b = new SolidBrush(this.ForeColor))
                {
                    e.Graphics.DrawString(text, this.Font, b, new PointF(y, 4));
                }
                y += (int)size.Height + 3;
            }

            Rectangle area = new Rectangle(1, y, this.Width - 2, 1);
            Color back = this.BackColor;
            using (LinearGradientBrush lgt = new LinearGradientBrush(area, this._LineColorTop, back, 0f))
            {
                e.Graphics.FillRectangle(lgt, area);
            }
            y += 1;

            area = new Rectangle(1, y, this.Width - 2, 1);
            using (LinearGradientBrush lgb = new LinearGradientBrush(area, this._LineColorBottom, back, 0f))
            {
                e.Graphics.FillRectangle(lgb, area);
            }
            y += 2;

            this.Height = y + 1;
        }

        [RefreshProperties(RefreshProperties.All)]
        [NotifyParentProperty(true)]
        [DefaultValue("")]
        [Description("Titulkový text")]
        [Category(GuiConst.CATEGORY)]
        public string Title { get { return this._Title; } set { this._Title = value; this.RePaint(); } } private string _Title;

        [RefreshProperties(RefreshProperties.All)]
        [NotifyParentProperty(true)]
        [DefaultValue(typeof(Color), "192, 192, 216")]
        [Description("Barva vlevo")]
        [Category(GuiConst.CATEGORY)]
        public Color LineColorTop { get { return this._LineColorTop; } set { this._LineColorTop = value; this.RePaint(); } } private Color _LineColorTop;
        [RefreshProperties(RefreshProperties.All)]
        [NotifyParentProperty(true)]
        [DefaultValue(typeof(Color), "192, 192, 216")]
        [Description("Barva vlevo")]
        [Category(GuiConst.CATEGORY)]
        public Color LineColorBottom { get { return this._LineColorBottom; } set { this._LineColorBottom = value; this.RePaint(); } } private Color _LineColorBottom;

        protected void RePaint()
        {
            this.Invalidate();
        }
    }
    #endregion
    #region ImageCheckBox
    public class ImageCheckBox : CheckBox
    {
        public ImageCheckBox()
        {
            this.SetStyle(ControlStyles.SupportsTransparentBackColor | ControlStyles.OptimizedDoubleBuffer, true);
            this.BackColor = Color.Transparent;
        }
        protected override void OnPaint(PaintEventArgs pevent)
        {
            base.OnPaint(pevent);
        }
    }
    #endregion
    #region FlatActiveButton
    /// <summary>
    /// ActiveButton plochý
    /// </summary>
    public class FlatActiveButton : ActiveButton
    {
        public FlatActiveButton()
        {
            this.FlatAppearance.BorderSize = 0;
            this.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
            this.TabStop = false;
            this.Margin = new System.Windows.Forms.Padding(0);
            this.Text = "";
            this.TextImageRelation = System.Windows.Forms.TextImageRelation.TextAboveImage;
            this.UseVisualStyleBackColor = false;
        }
    }
    #endregion
    #region ActiveButton
    /// <summary>
    /// Active button (with two image)
    /// </summary>
    public class ActiveButton : Button
    {
        /// <summary>
        /// Constructor
        /// </summary>
        public ActiveButton()
        {
            this.SetStyle(ControlStyles.SupportsTransparentBackColor | ControlStyles.OptimizedDoubleBuffer, true);
            this.BackColor = Color.Transparent;
            this.ImageAlign = ContentAlignment.MiddleCenter;
            this.TabStop = false;
            this.Text = "";
            this.Image = Resources.dialog_cancel_3_22;
            this.ImageStd = Resources.dialog_cancel_3_22;
            this.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;

            this.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
            this.FlatAppearance.MouseOverBackColor = Color.Transparent;
            this.FlatAppearance.MouseDownBackColor = Color.Transparent;
            this.FlatAppearance.BorderColor = SystemColors.GradientActiveCaption;
            this.FlatAppearance.BorderSize = 0;

            this.MouseEnter += new EventHandler(ActiveButton_MouseEnter);
            this.MouseLeave += new EventHandler(ActiveButton_MouseLeave);
            this.MouseMove += new MouseEventHandler(ActiveButton_MouseMove);
            this.MouseDown += new MouseEventHandler(ActiveButton_MouseDown);
            this.MouseUp += new MouseEventHandler(ActiveButton_MouseUp);
            this.Enter += new EventHandler(ActiveButton_Enter);
            this.Leave += new EventHandler(ActiveButton_Leave);
            this.EnabledChanged += new EventHandler(ActiveButton_EnabledChanged);
        }
        /// <summary>
        /// Image in standard mode
        /// </summary>
        [Category(GuiConst.CATEGORY)]
        [Description("Image in standard mode")]
        public Image ImageStd { get; set; }
        /// <summary>
        /// Image in hot-mouse mode
        /// </summary>
        [Category(GuiConst.CATEGORY)]
        [Description("Image in hot-mouse mode")]
        public Image ImageHot { get; set; }
        /// <summary>
        /// Image in hot-mouse mode
        /// </summary>
        [Category(GuiConst.CATEGORY)]
        [Description("Image in down-mouse mode")]
        public Image ImageDown { get; set; }
        /// <summary>
        /// Show border when active
        /// </summary>
        [Category(GuiConst.CATEGORY)]
        [Description("Show border when active")]
        public bool ShowActiveBorder { get; set; }
        /// <summary>
        /// State of button
        /// </summary>
        public ActiveButtonState ButtonState { get { return this._ButtonState; } private set { this._ButtonState = value; this._ShowGui(); } } private ActiveButtonState _ButtonState;
        #region Private event handlers
        void ActiveButton_EnabledChanged(object sender, EventArgs e)
        {
            if (!this.Enabled)
            {
                this.ButtonState = ActiveButtonState.Disabled;
            }
            else if (this.ButtonState == ActiveButtonState.Disabled)
            {
                this._SaveImageStd();
                this.ButtonState = ActiveButtonState.Standard;
            }
        }
        void ActiveButton_MouseEnter(object sender, EventArgs e)
        {
            if (this.Enabled)
            {
                this._SaveImageStd();
                this._WaitToEnter = false;
                this.ButtonState = ActiveButtonState.Active;
            }
        }
        void ActiveButton_MouseMove(object sender, MouseEventArgs e)
        {
            if (this.Enabled && this.ButtonState != ActiveButtonState.Active && !this._WaitToEnter)
            {
                this._SaveImageStd();
                this.ButtonState = ActiveButtonState.Active;
            }
        }
        void ActiveButton_MouseDown(object sender, MouseEventArgs e)
        {
            if (this.Enabled)
            {
                this._WaitToEnter = true;
                this.ButtonState = ActiveButtonState.Down;
            }
        }
        void ActiveButton_MouseUp(object sender, MouseEventArgs e)
        {
            if (this.Enabled)
            {
                this._WaitToEnter = true;
                this.ButtonState = ActiveButtonState.Standard;
            }
        }
        void ActiveButton_MouseLeave(object sender, EventArgs e)
        {
            this._WaitToEnter = false;
            if (this.Enabled)
                this.ButtonState = ActiveButtonState.Standard;
        }
        void ActiveButton_Enter(object sender, EventArgs e)
        {
            if (this.Enabled && this.TabStop)
            {
                this._SaveImageStd();
                this.ButtonState = ActiveButtonState.Active;
            }
        }
        void ActiveButton_Leave(object sender, EventArgs e)
        {
            if (this.Enabled && this.TabStop)
            {
                this.ButtonState = ActiveButtonState.Standard;
            }
        }
        private void _SaveImageStd()
        {
            if (this.ButtonState == ActiveButtonState.Standard && this.Enabled && this.ImageStd == null && this.Image != null)
                this.ImageStd = this.Image;
        }
        private void _ShowGui()
        {
            Image image = null;
            int? borderSize = null;
            Color? borderColor = null;
            switch (this.ButtonState)
            {
                case ActiveButtonState.Disabled:
                    break;
                case ActiveButtonState.Standard:
                    image = this.ImageStd;
                    borderSize = 0;
                    break;
                case ActiveButtonState.Active:
                    image = this.ImageHot;
                    borderSize = (this.ShowActiveBorder ? 1 : 0);
                    borderColor = (this.ShowActiveBorder ? (Color?)Color.LightGray : (Color?)null);
                    break;
                case ActiveButtonState.Down:
                    image = this.ImageDown;
                    borderSize = (this.ShowActiveBorder ? 1 : 0);
                    borderColor = (this.ShowActiveBorder ? (Color?)Color.DarkGray : (Color?)null);
                    break;
            }
            if (image != null)
                this.Image = image;
            if (borderSize.HasValue && borderSize.Value != this.FlatAppearance.BorderSize)
                this.FlatAppearance.BorderSize = borderSize.Value;
            if (borderColor.HasValue && borderColor.Value != this.FlatAppearance.BorderColor)
                this.FlatAppearance.BorderColor = borderColor.Value;
        }
        private bool _WaitToEnter;
        #endregion
    }
    public enum ActiveButtonState
    {
        None = 0,
        Disabled,
        Standard,
        Active,
        Down
    }
    #endregion
    #region GuiConst
    public static class GuiConst
    {
        public const string CATEGORY = "DJ soft";
    }
    #endregion
}
